package com.jbl.st.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jbl.commonutils.R;
import com.jbl.exceptionhandler.ManagerException;
import com.jbl.st.entity.CourseclassStudent;
import com.jbl.st.entity.dto.SelectQuery;
import com.jbl.st.entity.vo.CourseclassSelectVO;
import com.jbl.st.service.CourseclassStudentService;
import com.jbl.te.entity.Course;
import com.jbl.te.entity.Courseclass;
import com.jbl.te.entity.Teacher;
import com.jbl.te.quartz.SelectEndJob;
import com.jbl.te.service.CourseService;
import com.jbl.te.service.CourseclassService;
import com.jbl.te.service.CourseclassTimeService;
import com.jbl.te.service.TeacherService;
import io.swagger.annotations.ApiOperation;
import org.quartz.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@RestController
@RequestMapping("/st/courseSelect")
@CrossOrigin
public class courseSelectController {

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    Scheduler scheduler; //调度器
    @Autowired
    CourseclassService courseclassService;
    @Autowired
    private CourseclassTimeService timeService;
    @Autowired
    private TeacherService teacherService;
    @Autowired
    private CourseService courseService;
    @Autowired
    private CourseclassStudentService courseclassStudentService;

    @GetMapping("/startSelect")
    @ApiOperation("启动选课")
    public R startSelect(String begin, String end) throws ParseException, SchedulerException {

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date beginTime = format.parse(begin);
        Date endTime = format.parse(end);
        int compare = beginTime.compareTo(endTime);
        if(compare >= 0) throw new ManagerException(20001,"起始时间必须小于截止时间！");
        Date cur = new Date();
        int compare1 = cur.compareTo(beginTime);
        if(compare1 >= 0) throw new ManagerException(20001,"起始时间必须大于当前时间！");


        //redis加入两个时间
        ValueOperations ops = redisTemplate.opsForValue();
        ops.set("student_courseclass_begin",begin);
        redisTemplate.persist("student_courseclass_begin"); //设置永不过期
        ops.set("student_courseclass_end",end);
        redisTemplate.persist("student_courseclass_end"); //设置永不过期

        //定时任务
        //触发器
        format = new SimpleDateFormat("ss mm HH dd MM ? yyyy"); //date转换成cron
        String cornTime = format.format(endTime);
        System.out.println(cornTime);
        CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1","group1").
                withSchedule(CronScheduleBuilder.cronSchedule(cornTime)).build();
        //JobDetail
        JobDetail jobDetail = JobBuilder.newJob(SelectEndJob.class)
                .withIdentity("job1","group1")
                .build();
        //触发器和jobDetail添加到调度器中
        scheduler.scheduleJob(jobDetail, trigger);
        //启动
        scheduler.start();

        return R.ok();
    }

    @GetMapping("/closeSelect")
    @ApiOperation("关闭选课")
    public R closeSelect() throws SchedulerException {
        System.out.println("=======关闭选课=========");
        redisTemplate.delete("student_courseclass_begin");
        redisTemplate.delete("student_courseclass_end");

        TriggerKey triggerKey = TriggerKey.triggerKey("trigger1","group1");

        scheduler.pauseTrigger(triggerKey); //停止触发器
        boolean b1 = scheduler.unscheduleJob(triggerKey);//移除触发器
        boolean b = scheduler.deleteJob(JobKey.jobKey("job1", "group1"));//删除任务
        System.out.println("###"+b1+b);

        return R.ok();
    }

    @GetMapping("/getSelectTime")
    @ApiOperation("获取选课时间")
    public R getSelectTime() throws ParseException {
        if(!redisTemplate.hasKey("student_courseclass_begin") || !redisTemplate.hasKey("student_courseclass_end")) {
            return R.ok();
        }
        ValueOperations ops = redisTemplate.opsForValue();
        String begin = (String) ops.get("student_courseclass_begin");
        String end = (String) ops.get("student_courseclass_end");

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date beginTime = format.parse(begin);
        Date endTime = format.parse(end);

        return R.ok().data("begin",beginTime).data("end",endTime);
    }

    @GetMapping("/getFlag")
    @ApiOperation("根据时间生成flag")
    public R getFlag() throws ParseException {
        if(!redisTemplate.hasKey("student_courseclass_begin") || !redisTemplate.hasKey("student_courseclass_end")) {
            return R.ok().data("flag",0);
        }
        Integer flag;
        ValueOperations ops = redisTemplate.opsForValue();
        String begin = (String) ops.get("student_courseclass_begin");
        String end = (String) ops.get("student_courseclass_end");

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date beginTime = format.parse(begin);
        Date endTime = format.parse(end);

        Date cur = new Date();
//        System.out.println("===============");
//        System.out.println(cur);
//        System.out.println(begin);
//        System.out.println(end);

        int compare1 = cur.compareTo(beginTime);
        int compare2 = cur.compareTo(endTime);

        if(compare1 < 0) flag = 1;
        else if(compare1 >= 0 && compare2 < 0) flag = 2;
        else flag = 3;

        return R.ok().data("flag",flag);

    }

    @GetMapping("/getCourseclassSelectById")
    @ApiOperation("根据id获取选课")
    public R getCourseclassSelectById(String studentId, String courseclassId) {
        CourseclassSelectVO vo = new CourseclassSelectVO();
        Courseclass courseclass = courseclassService.getById(courseclassId);
        BeanUtils.copyProperties(courseclass,vo);
        Course course = courseService.getById(courseclass.getCourseId());
        BeanUtils.copyProperties(course,vo);
        vo.setCourseName(course.getName());
        Teacher teacher = teacherService.getById(courseclass.getTeacherId());
        vo.setTeacherName(teacher.getName());

        //已选人数，未选人数
        QueryWrapper<CourseclassStudent> courseclassStudentQueryWrapper = new QueryWrapper<>();
        courseclassStudentQueryWrapper.eq("courseclass_id",courseclass.getId());
        courseclassStudentQueryWrapper.eq("state",1);
        vo.setSelected(courseclassStudentService.count(courseclassStudentQueryWrapper));
        vo.setNoneSelected(vo.getLimitNumber()-vo.getSelected());
        vo.setId(courseclass.getId());

        //通过课程班id和学生id获取选课状态
        courseclassStudentQueryWrapper = new QueryWrapper<>();
        courseclassStudentQueryWrapper.eq("student_id",studentId);
        courseclassStudentQueryWrapper.eq("courseclass_id",courseclass.getId());
        CourseclassStudent courseclassStudent = courseclassStudentService.getOne(courseclassStudentQueryWrapper);
        if(courseclassStudent == null) vo.setState(0); //未选
        else {
            if(courseclassStudent.getState()) vo.setState(1); //已选
            else vo.setState(2); //退选
        }

        return R.ok().data("courseclass",vo);
    }

    @PostMapping("/getAllCourseclassSelect")
    @ApiOperation("获取所有选课")
    public R getAllCourseclassSelect(@RequestBody SelectQuery selectQuery) {
        String studentId = selectQuery.getStudentId();
        String courseName = selectQuery.getName();
        Integer courseType = selectQuery.getCourseType();

        //状态为未确定的课才列入选课
        QueryWrapper<Courseclass> courseclassQueryWrapper = new QueryWrapper<>();
        courseclassQueryWrapper.eq("is_confirm",0);
        //根据条件筛选课程班
        QueryWrapper<Course> courseQueryWrapper = new QueryWrapper<>();
        courseQueryWrapper.select("id");
        //课程名
        if(!StringUtils.isEmpty(courseName)) {
            courseQueryWrapper.like("name",courseName);
        }
        //课程类型
        if(!StringUtils.isEmpty(courseType)) {
            courseQueryWrapper.eq("course_type",courseType);
        }
        //获取所有符合条件的课程id
        List<Course> courseList= courseService.list(courseQueryWrapper);
        ArrayList idList = new ArrayList();
        for (Course course : courseList) {
            idList.add(course.getId());
        }
        if(!idList.isEmpty()) courseclassQueryWrapper.in("course_id",idList);

        List<Courseclass> courseclassList = courseclassService.list(courseclassQueryWrapper);
        List<CourseclassSelectVO> voList = new ArrayList<>();
        for (Courseclass courseclass : courseclassList) {
            CourseclassSelectVO vo = new CourseclassSelectVO();
            BeanUtils.copyProperties(courseclass,vo);

            Course course = courseService.getById(courseclass.getCourseId());
            if(course == null) throw new ManagerException(20001,"该课程班未匹配课程");
            BeanUtils.copyProperties(course,vo);
            vo.setCourseName(course.getName());


            Teacher teacher = teacherService.getById(courseclass.getTeacherId());
            if(teacher == null) throw new ManagerException(20001,"该课程班未匹配教师");
            vo.setTeacherId(teacher.getId());
            vo.setTeacherName(teacher.getName());

            //已选人数，未选人数
            QueryWrapper<CourseclassStudent> courseclassStudentQueryWrapper = new QueryWrapper<>();
            courseclassStudentQueryWrapper.eq("courseclass_id",courseclass.getId());
            courseclassStudentQueryWrapper.eq("state",1);
            vo.setSelected(courseclassStudentService.count(courseclassStudentQueryWrapper));
            vo.setNoneSelected(vo.getLimitNumber()-vo.getSelected());
            vo.setId(courseclass.getId());

            //通过课程班id和学生id获取选课状态
            courseclassStudentQueryWrapper = new QueryWrapper<>();
            courseclassStudentQueryWrapper.eq("student_id",studentId);
            courseclassStudentQueryWrapper.eq("courseclass_id",courseclass.getId());
            CourseclassStudent courseclassStudent = courseclassStudentService.getOne(courseclassStudentQueryWrapper);
            if(courseclassStudent == null) vo.setState(0); //未选
            else {
                if(courseclassStudent.getState()) vo.setState(1); //已选
                else vo.setState(2); //退选
            }
            voList.add(vo);
        }
        return R.ok().data("list",voList);
    }

    @PutMapping("/updateConfirmToTrue")
    @ApiOperation("所有未确定课程班改为已确定")
    public R updateConfirmToTrue() {
        QueryWrapper<Courseclass> wrapper = new QueryWrapper<>();
        wrapper.eq("is_confirm",0);
        List<Courseclass> list = courseclassService.list(wrapper);
        for (Courseclass courseclass : list) {
            courseclass.setIsConfirm(true);
            courseclassService.updateById(courseclass);
        }
        return R.ok();
    }

    @PostMapping("/saveCourseclassStudent")
    @ApiOperation("学生选课，中间表添加记录")
    public R saveCourseclassStudent(String studentId, String courseclassId) {
        QueryWrapper<CourseclassStudent> wrapper = new QueryWrapper<>();
        wrapper.eq("student_id",studentId);
        wrapper.eq("courseclass_id",courseclassId);
        CourseclassStudent courseclassStudent = courseclassStudentService.getOne(wrapper);
        if(courseclassStudent != null) courseclassStudentService.removeById(courseclassStudent); //退选的课先删掉
        courseclassStudent = new CourseclassStudent();
        courseclassStudent.setStudentId(studentId);
        courseclassStudent.setCourseclassId(courseclassId);
        courseclassStudent.setState(true);
        Boolean save = courseclassStudentService.saveCourseclassStudent(courseclassStudent);
        if(!save) return R.error().message("选课失败！可能原因是人数已满");
        return R.ok();
    }

    @GetMapping("/getSelectedCourseclass")
    @ApiOperation("获取任选结果")
    public R getSelectedCourseclass(String studentId) {

        QueryWrapper<CourseclassStudent> wrapper = new QueryWrapper<>();
        wrapper.eq("student_id",studentId);
        wrapper.eq("state",1);
        List<CourseclassStudent> courseclassStudentList = courseclassStudentService.list(wrapper);
        List<CourseclassSelectVO> voList = new ArrayList<>();
        for (CourseclassStudent courseclassStudent : courseclassStudentList) {
            CourseclassSelectVO vo = new CourseclassSelectVO();
            Courseclass courseclass = courseclassService.getById(courseclassStudent.getCourseclassId());//查出该学生所有已选的课程班
            BeanUtils.copyProperties(courseclass,vo);

            Course course = courseService.getById(courseclass.getCourseId());
            if(course == null) throw new ManagerException(20001,"该课程班未匹配课程");
            BeanUtils.copyProperties(course,vo);
            vo.setCourseName(course.getName());


            Teacher teacher = teacherService.getById(courseclass.getTeacherId());
            if(teacher == null) throw new ManagerException(20001,"该课程班未匹配教师");
            vo.setTeacherId(teacher.getId());
            vo.setTeacherName(teacher.getName());

            //已选人数，未选人数
            QueryWrapper<CourseclassStudent> courseclassStudentQueryWrapper = new QueryWrapper<>();
            courseclassStudentQueryWrapper.eq("courseclass_id",courseclass.getId());
            vo.setSelected(courseclassStudentService.count(courseclassStudentQueryWrapper));
            vo.setNoneSelected(vo.getLimitNumber()-vo.getSelected());
            vo.setId(courseclass.getId());

            voList.add(vo);
        }
        return R.ok().data("list",voList);
    }

    @GetMapping("/getQuitCourseclass")
    @ApiOperation("获取退选结果")
    public R getQuitCourseclass(String studentId) {
        QueryWrapper<CourseclassStudent> wrapper = new QueryWrapper<>();
        wrapper.eq("student_id",studentId);
        wrapper.eq("state",0);
        List<CourseclassStudent> courseclassStudentList = courseclassStudentService.list(wrapper);
        List<CourseclassSelectVO> voList = new ArrayList<>();
        for (CourseclassStudent courseclassStudent : courseclassStudentList) {
            CourseclassSelectVO vo = new CourseclassSelectVO();
            Courseclass courseclass = courseclassService.getById(courseclassStudent.getCourseclassId());//查出该学生所有已选的课程班
            BeanUtils.copyProperties(courseclass,vo);

            Course course = courseService.getById(courseclass.getCourseId());
            if(course == null) throw new ManagerException(20001,"该课程班未匹配课程");
            BeanUtils.copyProperties(course,vo);
            vo.setCourseName(course.getName());


            Teacher teacher = teacherService.getById(courseclass.getTeacherId());
            if(teacher == null) throw new ManagerException(20001,"该课程班未匹配教师");
            vo.setTeacherId(teacher.getId());
            vo.setTeacherName(teacher.getName());

            //已选人数，未选人数
            QueryWrapper<CourseclassStudent> courseclassStudentQueryWrapper = new QueryWrapper<>();
            courseclassStudentQueryWrapper.eq("courseclass_id",courseclass.getId());
            courseclassStudentQueryWrapper.eq("state",1);
            vo.setSelected(courseclassStudentService.count(courseclassStudentQueryWrapper));
            vo.setNoneSelected(vo.getLimitNumber()-vo.getSelected());
            vo.setId(courseclass.getId());

            voList.add(vo);
        }
        return R.ok().data("list",voList);
    }

    @DeleteMapping("/delCourseclassStudent")
    @ApiOperation("学生退选，中间表修改记录状态")
    public R delCourseclassStudent(String studentId, String courseclassId) {
        QueryWrapper<CourseclassStudent> wrapper = new QueryWrapper<>();
        wrapper.eq("student_id",studentId);
        wrapper.eq("courseclass_id",courseclassId);
        CourseclassStudent courseclassStudent = courseclassStudentService.getOne(wrapper);
        if(courseclassStudent != null) {
            courseclassStudent.setState(false);
            courseclassStudentService.updateById(courseclassStudent);
        }
        return R.ok();
    }

}
